package com.yl.immodule.util;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.android.yl.ylicpsdk.ICPRtcEventHandler;
import com.android.yl.ylicpsdk.ICPRtcManager;
import com.camera.base.inerface.CameraServiceSingleton;
import com.camera.base.inerface.FramePusher;
import com.camera.base.inerface.H264Buffer;
import com.camera.base.inerface.ICPInterface;
import com.camera.base.inerface.Pusher;
import com.camera.base.inerface.VideoFrame;
import com.camera.base.inerface.VideoFrameBufferType;
import com.camera.base.util.DefaultWebModelFactory;
import com.camera.base.wbmodels.WebModel;
import com.camera.routemodule.routeinterface.YLWebSocketInterface;
import com.google.gson.Gson;
import com.hm.poc.video.ExternalAudioConsumer;
import com.hm.poc.video.ExternalVideoConsumer;
import com.unionbroad.app.util.Logger;
import com.yl.immodule.R;
import com.yl.immodule.iminterface.MeetManagerInterface;

import java.nio.ByteBuffer;

public class MeetServerManager extends MeetManagerInterface{
    private final static String TAG = MeetServerManager.class.getSimpleName();
    Logger logger = Logger.getLogger("MeetWindowManager");
    long sessionId;
    String remoteId;
    String remoteName;
    int type;
    String extra;
    //来电或外呼
    boolean isIncomingCall;
    ICPRtcManager icpRtcManager = ICPRtcManager.getsInstance();
    public Context mContext;
    public FrameLayout meetLayout;
    public WindowManager mWindowManager;
    ICPInterface mICPInterface;
    private Handler handler = new Handler();
    TextView tvInDialogTitle,tvOutDialogTitle;
    Button btnInSure,btnInHanup,btnOut;
    public static boolean userLayout = false;//是否使用界面
    YLWebSocketInterface ylWebSocketInterface;
    DefaultWebModelFactory mWebModelFactory = new DefaultWebModelFactory();
    boolean isAddView = true;
    boolean isFullScreen;
    @Override
    public void setWebSocketServer(YLWebSocketInterface ylWebSocketInterface){
        this.ylWebSocketInterface = ylWebSocketInterface;
    }
    @Override
    public void showRometView(){
        view2WindowManger(true,false,100,100,0,0);
    }
    // 私有静态变量，存储唯一实例
    @Override
    public void stopMeet(){
        Log.e("TAG", "stopMeet: " );
        removeRemoteVideo();
        removeLocalVideo();
        icpRtcManager.removeEventHandler(mIcpRtcEventHandler);
        icpRtcManager.setExternalAudioConsumer(null);
        icpRtcManager.setExternalVideoConsumer(null);
    }
    @Override
    public void startMeet(Context context ,long sessionId,String remoteId,String remoteName,int type,String extra,boolean isIncomingCall){
        Log.e("TAG", "startMeet: ");
        icpRtcManager.getConfig();
        icpRtcManager.setExternalAudioConsumer(externalAudioConsumer);
        icpRtcManager.setExternalVideoConsumer(externalVideoConsumer);
        this.sessionId = sessionId;
        this.remoteId = remoteId;
        this.remoteName = remoteName;
        this.type = type;
        this.extra = extra;
        this.isIncomingCall = isIncomingCall;
        mContext = context;
        //监听必要的事件
        icpRtcManager.addEventHandler(mIcpRtcEventHandler);
        if (isIncomingCall) {
            //发送WebSocket  告送来电
            WebModel webModel = mWebModelFactory.createAVResultWebModelIM();
            webModel.getiMWebModel().getAvResultConfig().setCode(1001);
            webModel.getiMWebModel().getAvResultConfig().setTypeCode(type);
            webModel.getiMWebModel().getAvResultConfig().setRemoteName(remoteName);
            if (type == ICPRtcEventHandler.SessionType.TYPE_AUDIO_PTT_TEMP) {
                webModel.getiMWebModel().getAvResultConfig().setMessage("临时组来电");
            } else if (type == ICPRtcEventHandler.SessionType.TYPE_AUDIO_PTT) {
                webModel.getiMWebModel().getAvResultConfig().setMessage("对讲组来电");
            } else {
                webModel.getiMWebModel().getAvResultConfig().setMessage("来电");
            }
            logger.d("来电1" + webModel.getiMWebModel().getAvResultConfig());
            String jsonString = new Gson().toJson(webModel);
            ylWebSocketInterface.sendMessage(jsonString);
        } else {
            boolean ret = makeCall(remoteId, type);
            if (!ret) {
                stopMeet();//隐藏
            }
        }
    }

    public void removeLayout(){
        view2WindowManger(false,true,1,1,0,0);
    }
    /**
     * @param isFullScreen 全屏
     * 更新整个Service UI to WindowManager
     */
    public void view2WindowManger(boolean isFullScreen,boolean isRemove,int width,int height,int x,int y) {
        handler.post(new Runnable() {
            @SuppressLint("WrongConstant")
            @Override
            public void run() {
                if (meetLayout != null) {
                    WindowManager.LayoutParams layoutParams  = new WindowManager.LayoutParams();
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { //6.0
                        layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
                    } else {
                        layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
                    }
                    layoutParams.flags = (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH);
//                    if (isFullScreen) {
//                        layoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
//                        layoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
//                        layoutParams.flags = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
//                        layoutParams.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN;
//                        layoutParams.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
//                    } else {
                        layoutParams.width = width;
                        layoutParams.height = height;
                        layoutParams.x = x;
                        layoutParams.y = y;
                        // 1x1小窗口时候隐藏黑色遮布
//                               curtainView!!.visibility = View.VISIBLE
//                    }
                    if (isRemove){
                        isAddView = true;
                        Log.e("TAG", "run:  mWindowManager.removeView(meetLayout);" );
                        mWindowManager.removeView(meetLayout);
                        meetLayout = null;
                        mWindowManager = null;
                    }else{
                        if (isAddView) {
                            //
                            mWindowManager.addView(meetLayout, layoutParams);
                        } else {
                            mWindowManager.updateViewLayout(meetLayout, layoutParams);
                        }
                        isAddView = false;
                    }
                }
            }
        });
    }
    private final ExternalAudioConsumer externalAudioConsumer = new ExternalAudioConsumer() {
        @Override
        public void onAudioFrame(long sessionId, byte[] audioBytes, long dataLen) {
            //logger.i("onAudioFrame: " + dataLen);
        }
    };

    private final ExternalVideoConsumer externalVideoConsumer = new ExternalVideoConsumer() {
        @Override
        public void onVideoFrame(long sessionId, ByteBuffer byteBuffer) {
            logger.i("onVideoFrame: " + byteBuffer);
        }
    };

    final ICPRtcEventHandler mIcpRtcEventHandler = new ICPRtcEventHandler() {

        @Override
        public void onRemoteRinging(long sessionId, long uid) {
            WebModel webModel = mWebModelFactory.createAVResultWebModelIM();
            webModel.getiMWebModel().getAvResultConfig().setCode(1003);
            webModel.getiMWebModel().getAvResultConfig().setId(uid);
            String jsonString = new Gson().toJson(webModel);
            ylWebSocketInterface.sendMessage(jsonString);
        }

        @Override
        public void onCallConnected(long sessionId, String uid, int sessionType) {
            if (MeetServerManager.this.sessionId == sessionId) {
                logger.d(">>>>>>onCallConnected sessionId=" + sessionId + " uid=" + uid + " sessionType=" + sessionType);
                MeetServerManager.this.sessionId = sessionId;

                WebModel webModel = mWebModelFactory.createAVResultWebModelIM();
                webModel.getiMWebModel().getAvResultConfig().setCode(1007);
                webModel.getiMWebModel().getAvResultConfig().setTypeCode(sessionType);
                String jsonString = new Gson().toJson(webModel);
                ylWebSocketInterface.sendMessage(jsonString);

                /** 如果是一个视频呼叫，一般远端画面全屏，本地画面右上角小窗口显示 */
                if (sessionType == SessionType.TYPE_VIDEO_CALL ||
                        sessionType == SessionType.TYPE_VIDEO_MEETING) {
                    setupLocalVideo();
                    setupRemoteVideo();
                }
                /** 如果是一个视频回传呼叫、直播、报警呼叫，是没有远端画面的，把本地画面全屏显示即可 */
                else if (sessionType == SessionType.TYPE_VIDEO_MONITOR_CALL ||
                        sessionType == SessionType.TYPE_VIDEO_SOS_CALL ||
                        sessionType == SessionType.TYPE_VIDEO_LIVE) {
                    setupMonitorVideo();
                }
            }
        }

        @Override
        public void onCallDisconnected(long sessionId, int reason) {
            if (MeetServerManager.this.sessionId == sessionId) {
                WebModel webModel = mWebModelFactory.createAVResultWebModelIM();
                webModel.getiMWebModel().getAvResultConfig().setCode(1004);
                webModel.getiMWebModel().getAvResultConfig().setTypeCode(reason);
                String jsonString = new Gson().toJson(webModel);
                ylWebSocketInterface.sendMessage(jsonString);
                stopMeet();
            }
        }

        @Override
        public void onIgnoreIncoming(int type, long callerId) {
            //当前已有会话，新的来电被自动拒绝
            Toast.makeText(mContext, "有来电被拒绝"+callerId, Toast.LENGTH_SHORT).show();

            WebModel webModel = mWebModelFactory.createAVResultWebModelIM();
            webModel.getiMWebModel().getAvResultConfig().setCode(1006);
            webModel.getiMWebModel().getAvResultConfig().setId(callerId);
            String jsonString = new Gson().toJson(webModel);
            ylWebSocketInterface.sendMessage(jsonString);
        }

        @Override
        public void onRemoteVideoPause(boolean pause) {
            if (pause) {
                //去掉两个SurfaceView，并显示一张图片
                removeLocalVideo();
                removeRemoteVideo();
            } else {
                //重新显示SurfaceView
                setupRemoteVideo();
                setupLocalVideo();
            }
        }

        @Override
        public void onVideoStreamRecordFinish(String filePath) {
            if (TextUtils.isEmpty(filePath)) {
                Toast.makeText(mContext, "录制失败", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(mContext, "文件保存到：" + filePath, Toast.LENGTH_SHORT).show();
            }
        }

        @Override
        public void onVideoStreamTakePictureFinish(String filePath) {
            Toast.makeText(mContext, "拍照成功->" + filePath, Toast.LENGTH_SHORT).show();
        }
    };
    private void getCameraInterface() {
        mICPInterface = CameraServiceSingleton.INSTANCE.getInstance();
    }
    MFramePusher pusher;
    public class MFramePusher extends FramePusher {
        public MFramePusher(int type) {
            super(type);
        }

        @Override
        public void onFrame(VideoFrame farme) {
            if (farme.getBuffer().getBufferType() == VideoFrameBufferType.H264_PCM_BUFFER) {
                icpRtcManager.pushVideoFrame(sessionId,((H264Buffer) farme.getBuffer()).getData() ,((H264Buffer) farme.getBuffer()).getData().length);
            }
        }
    }
    private void setupLocalVideo() {
        getCameraInterface();
        Log.e("TAG", "setupLocalVideo: " +(mICPInterface != null));
        if (mICPInterface != null){
            //首先要确保CameraManager 中的摄像头服务已经驱动
            pusher = new MFramePusher(VideoFrameBufferType.H264_PCM_BUFFER);
            if (!mICPInterface.isICPCameraOpen()){
                mICPInterface.openICPCamera();
            }
            mICPInterface.addSubcodeStreamPusher(pusher);
            mICPInterface.requestKeyFrame(5);
        }

    }
    private void setupRemoteVideo() {
        if (meetLayout == null){
            mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
            meetLayout = (FrameLayout)View.inflate(mContext, R.layout.romte_camera_ui, null);
        }
        if (meetLayout.getChildCount() > 0) {
            meetLayout.removeAllViews();
        }
        View surfaceView = icpRtcManager.getRendererView(ICPRtcEventHandler.SurfaceType.REMOTE);
        if (surfaceView != null) {
            meetLayout.addView(surfaceView);
            view2WindowManger(true,false,1,1,0,0);
            //通知websocket 设置窗口大小
        } else {
            logger.d("get remote surface view null");
        }
    }
    private void removeLocalVideo() {
        if(mICPInterface != null && pusher!= null){
            mICPInterface.removeSubcodeStream(pusher);
        }
    }
    private void removeRemoteVideo() {
        Log.e("TAG", "removeRemoteVideo: " );
        if (meetLayout != null){
            meetLayout.removeAllViews();
        }
        removeLayout();
    }
    private boolean makeCall(String id, int sessionType) {
        if (TextUtils.isEmpty(id)) {
            Toast.makeText(mContext, "无效id", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (!icpRtcManager.hasServiceConnected()) {
            Toast.makeText(mContext, "服务连接已断开", Toast.LENGTH_SHORT).show();
            return false;
        }
        if (sessionType == ICPRtcEventHandler.SessionType.TYPE_VIDEO_CALL) {
            sessionId = icpRtcManager.makeVideoCall(id + "", "args");
        } else if (sessionType == ICPRtcEventHandler.SessionType.TYPE_VIDEO_MONITOR_CALL
                || sessionType == ICPRtcEventHandler.SessionType.TYPE_AUDIO_MONITOR_CALL) {
            sessionId = icpRtcManager.makeVideoMonitorCall(id);
        } else if (sessionType == ICPRtcEventHandler.SessionType.TYPE_VIDEO_SOS_CALL) {
            sessionId = icpRtcManager.makeVideoSOSCall(id);
        } else if (sessionType == ICPRtcEventHandler.SessionType.TYPE_VIDEO_MEETING) {
            sessionId = icpRtcManager.makeVideoMeeting(id);
        }else if (sessionType == ICPRtcEventHandler.SessionType.TYPE_AUDIO_MEETING) {
            sessionId = icpRtcManager.makeAudioMeeting(id);
        } else {
            sessionId = icpRtcManager.makeAudioCall(id + "", "args");
        }
        WebModel webModel = mWebModelFactory.createAVResultWebModelIM();
        webModel.getiMWebModel().getAvResultConfig().setCode(1002);
        webModel.getiMWebModel().getAvResultConfig().setStatus(sessionId > 0?true:false);
        String jsonString = new Gson().toJson(webModel);
        ylWebSocketInterface.sendMessage(jsonString);
        return sessionId > 0;
    }
    /**
     * 点对点接听 和 对讲组接听
     */
    @Override
    public void tryAcceptCall() {
        if (type == ICPRtcEventHandler.SessionType.TYPE_AUDIO_PTT || type == ICPRtcEventHandler.SessionType.TYPE_AUDIO_PTT_TEMP) {
            boolean ret = icpRtcManager.joinChannel(remoteId);
            if (!ret) {
                Toast.makeText(mContext, "接听失败：" + sessionId, Toast.LENGTH_SHORT).show();
                tryHangUp();
            }
            stopMeet();
            //对讲组接听成功后，要退出来电界面，如果是对讲组来电，一般使用全局dialog就好，这里跳到AvActivity只是为了方便
        } else {
            boolean ret = icpRtcManager.acceptCall(sessionId);
            Log.e(TAG, "tryAcceptCall: "+ sessionId);
            if (!ret) {
                Toast.makeText(mContext, "接听失败：" + sessionId, Toast.LENGTH_SHORT).show();
                stopMeet();
            }
        }
    }
    @Override
    public void tryHangUp() {
        icpRtcManager.hangUpCall(sessionId);
        Log.e(TAG, "tryHangUp: "+ sessionId);
        stopMeet();
    }
    private void setupMonitorVideo() {
        meetLayout.findViewById(R.id.local_video_view_container).setVisibility(View.GONE);
        FrameLayout container = (FrameLayout) meetLayout.findViewById(R.id.remote_video_view_container);
        container.setVisibility(View.VISIBLE);
        if (container.getChildCount() > 0) {
            container.removeAllViews();
        }
        View surfaceView = icpRtcManager.getRendererView(ICPRtcEventHandler.SurfaceType.LOCAL);
        if (surfaceView != null) {
            container.addView(surfaceView);
            icpRtcManager.sendLocalVideo();
        } else {
            logger.d("get local surface view null");
        }
    }
}
